package com.cfcc.deptone.assetbarcodemgr.task;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Message;
import android.util.Log;
import android.widget.ArrayAdapter;

import com.cfcc.deptone.assetbarcodemgr.R;
import com.cfcc.deptone.assetbarcodemgr.activity.AssetActivity;
import com.cfcc.deptone.assetbarcodemgr.adapter.AssetLvArrayAdapter;
import com.cfcc.deptone.assetbarcodemgr.constant.AssetConstants;
import com.cfcc.deptone.assetbarcodemgr.entity.Product;
import com.cfcc.deptone.assetbarcodemgr.wrapper.ProductWrap;
import com.orhanobut.logger.Logger;

public class AssetListTask extends AsyncTask<String,Integer,List> {

	private static final String TAG = AssetListTask.class.getSimpleName();

	private AssetActivity activity;
	private String pandianFlg;

	public AssetListTask(AssetActivity activity) {
		this.activity = activity;
	}
	
	@Override
	protected void onPostExecute(List result) {
		Log.e(TAG,"size: "+result.size());
		this.activity.getPd().cancel();
		this.activity.setAdapter(new AssetLvArrayAdapter(this.activity, R.layout.asset_list, result));
		this.activity.getAssetLv().setAdapter(this.activity.getAdapter());
		this.activity.getAdapter().notifyDataSetChanged();

		String pandian_Chinese = "";
		if(AssetConstants.PANDIAN.equals(pandianFlg)) {
			pandian_Chinese = AssetConstants.PANDIAN_CHINESE;
		} else if(AssetConstants.NO_PANDIAN.equals(pandianFlg)) {
			pandian_Chinese = AssetConstants.NO_PANDIAN_CHINESE;
		}
		String summary = String.format(
				AssetConstants.ASSET_LV_SUMMARY_TV_FORMAT,
				pandian_Chinese,
				result.size());

		this.activity.getAssetLvSummaryTv().setText(summary);

		super.onPostExecute(result);
	}

	@Override
	protected void onProgressUpdate(Integer... values) {
		// TODO Auto-generated method stub
		super.onProgressUpdate(values);
		if(this.activity.getPd() != null)
			this.activity.getPd().setProgress(values[0]);
		else {
			Log.e(TAG, "pd is null");
			Logger.e("pd is null");
		}
	
	}

	@Override
	protected List doInBackground(String... params) {
		pandianFlg = params[0];
		//Log.e(TAG,"params[0]:"+params[0]);
		//return searchByBufferedMultiLine(params);
		//return searchByMapBuffered(params);
		return searchByBufferedEachLine(activity.getFilePath(), params);
		//return searchByBuffered(params);
		//return searchByRandom(params);
	}

	/**
	 * 利用缓冲区读取，每次读取一个字段
	 * @param params
	 * @return
	 */
	private List searchByBuffered(String... params) {
		List retList = new ArrayList();
    	FileInputStream fis = null;
    	//BufferedReader br = null;
    	BufferedInputStream bis = null;
    	int pos = 0;
    	int oldProgress = 0;
		try {
			File file = new File(Environment.getExternalStorageDirectory().getPath()+File.separator+
					AssetConstants.PANDIAN_FILE_NAME);
			fis = new FileInputStream(file);
			//br = new BufferedReader(new InputStreamReader(fis,Charset.forName("GBK")));
			bis = new BufferedInputStream(fis);
			String content = null;
			Long size = file.length();
			int line = (int) (size / AssetConstants.LINE_CHARS);
			//while( (content = br.readLine()) != null) {
			for(int i = 0; i < line; i++) {
				//Product product = ProductWrap.getProduct(content, pos);
				Product product = ProductWrap.getProduct(bis, pos);
				Log.d(TAG,"pandian: "+product.getCheckinStatus());
				if(params[0].equals(product.getCheckinStatus())) {
					retList.add(product);
				}
				pos++;
				//Log.i(TAG,content);
				int progress = (pos* 100/line) ;
				
				
				if(oldProgress != progress) {
					oldProgress = progress;
					Log.e(TAG, "pos:"+ pos +" size: "+size + " line:" + line +" progress: "+progress);
					this.publishProgress(progress);
				}
			}
		} catch (FileNotFoundException e) {
			Log.e(TAG,e.getMessage());
		} finally {
			try {
				/*if(br != null) {
					br.close();
					br = null;
				}*/
				if(bis != null) {
					bis.close();
					bis = null;
				}
				if(fis != null) {
					fis.close();
					fis = null;
				}
			} catch (IOException e) {
				Log.e(TAG,e.getMessage());
			}
		}
    	
    	
    	return retList;
	}


	/**
	 * 利用缓冲区读入数据，并且一行一行的读
	 * ，减少IO次数
	 * @param params
	 * @return
	 */
	private List searchByBufferedEachLine(String filePath, String... params) {
		List retList = new ArrayList();
		FileInputStream fis = null;
		//BufferedReader br = null;
		BufferedInputStream bis = null;
		byte[] content = null;
		int pos = 0;
		int oldProgress = 0;
		try {
			File file = new File(filePath);
			fis = new FileInputStream(file);
			//br = new BufferedReader(new InputStreamReader(fis,Charset.forName("GBK")));
			bis = new BufferedInputStream(fis);
			Long size = file.length();
			int line = (int) (size / AssetConstants.LINE_CHARS);
			//while( (content = br.readLine()) != null) {
			for(int i = 0; i < line; i++) {
				content = new byte[AssetConstants.LINE_BYTES_ARRAY];
				bis.read(content,0,AssetConstants.LINE_CHARS);
				Product product = ProductWrap.getProduct(content, pos);
				content = null;
				//Log.d(TAG,"pandian: "+product.getCheckinStatus());
				if(params.length == 2) {
					if(params[0].equals(product.getCheckinStatus()) || params[1].equals(product.getCheckinStatus())) {
						retList.add(product);
					}
				} else if(params.length == 1) {
					if(params[0].equals(product.getCheckinStatus())) {
						retList.add(product);
					}
				}

				pos++;
				//Log.i(TAG,content);
				int progress = (pos* 100/line) ;


				if(oldProgress != progress) {
					oldProgress = progress;
					//Log.e(TAG, "pos:"+ pos +" size: "+size + " line:" + line +" progress: "+progress);
					this.publishProgress(progress);
				}
			}
		} catch (FileNotFoundException e) {
			Log.e(TAG,e.getMessage());
			Logger.e(e.getMessage());
		} catch (IOException e) {
			Log.e(TAG,e.getMessage());
			Logger.e(e.getMessage());
		} finally {
			try {
				/*if(br != null) {
					br.close();
					br = null;
				}*/
				if(bis != null) {
					bis.close();
					bis = null;
				}
				if(fis != null) {
					fis.close();
					fis = null;
				}
			} catch (IOException e) {
				Log.e(TAG,e.getMessage());
				Logger.e(e.getMessage());
			}
		}


		return retList;
	}


	/**
	 * 利用缓冲区读入数据，并且指定行数的读
	 * ，减少IO次数
	 * @param params
	 * @return
	 */
	private List searchByBufferedMultiLine(String... params) {
		List retList = new ArrayList();
		FileInputStream fis = null;
		//BufferedReader br = null;
		BufferedInputStream bis = null;
		byte[] content = null;
		int pos = 0;
		int oldProgress = 0;
		try {
			File file = new File(Environment.getExternalStorageDirectory().getPath()+File.separator+
					AssetConstants.PANDIAN_FILE_NAME);
			fis = new FileInputStream(file);
			bis = new BufferedInputStream(fis);
			Long size = file.length();
			//所有记录数
			int line = (int) (size / AssetConstants.LINE_CHARS);
			//发生IO的次数
			int readCnt = line / AssetConstants.EACH_IO_LINES;
			if(line % AssetConstants.EACH_IO_LINES != 0) {
				readCnt = readCnt + 1;
			}

			int contentSize = 512 * AssetConstants.EACH_IO_LINES;
			//实际每次读取的行数
			int eachLines = 0;
			//每次发生读取时的开始位置
			int beginPos = 0;
			//每次读取的字节数
			int eachTimeBytes = 0;
			List products = null;

			for(int i = 0; i < readCnt; i++) {
				content = new byte[contentSize];

				beginPos = readCnt * i;

				if(pos + AssetConstants.EACH_IO_LINES <= line) {
					//读取EACH_IO_LINES行
					eachLines = AssetConstants.EACH_IO_LINES;
					//每次读取的字节数
					eachTimeBytes = eachLines * AssetConstants.LINE_CHARS;
					bis.read(content,0,eachTimeBytes);
					products = ProductWrap.getProducts(content,
							beginPos,
							eachLines,
							params[0]);
					content = null;
				} else {
					//读取line - pos行
					eachLines = line - pos;
					eachTimeBytes = eachLines * AssetConstants.LINE_CHARS;
					bis.read(content,0,eachTimeBytes);
					products = ProductWrap.getProducts(content,
							beginPos,
							eachLines,
							params[0]);
					content = null;
				}
				pos = pos + eachLines;

				retList.addAll(products);
				/*if(params[0].equals(product.getCheckinStatus())) {
					retList.add(product);
				}*/
				//pos++;
				int progress = (pos* 100/line) ;


				if(oldProgress != progress) {
					oldProgress = progress;
					this.publishProgress(progress);
				}
			}
		} catch (FileNotFoundException e) {
			Log.e(TAG,e.getMessage());
		} catch (IOException e) {
			Log.e(TAG,e.getMessage());
		} finally {
			try {
				if(bis != null) {
					bis.close();
					bis = null;
				}
				if(fis != null) {
					fis.close();
					fis = null;
				}
			} catch (IOException e) {
				Log.e(TAG,e.getMessage());
			}
		}


		return retList;
	}


	/**
	 * 内存映射文件的方式读取
	 * @param params
	 * @return
	 */
	private List searchByMapBuffered(String... params) {
		List retList = new ArrayList();
		FileInputStream fis = null;
		//BufferedReader br = null;
		//BufferedInputStream bis = null;
		FileChannel fc = null;
		MappedByteBuffer mappedBuf = null;

		byte[] content = null;
		int pos = 0;
		int oldProgress = 0;
		try {
			File file = new File(Environment.getExternalStorageDirectory().getPath()+File.separator+
					AssetConstants.PANDIAN_FILE_NAME);
			fis = new FileInputStream(file);
			fc = fis.getChannel();
			//bis = new BufferedInputStream(fis);
			Long size = file.length();
			mappedBuf = fc.map(FileChannel.MapMode.READ_ONLY, 0, size);

			//所有记录数
			int line = (int) (size / AssetConstants.LINE_CHARS);
			//发生IO的次数
			int readCnt = line / AssetConstants.EACH_IO_LINES;
			if(line % AssetConstants.EACH_IO_LINES != 0) {
				readCnt = readCnt + 1;
			}

			int contentSize = 512 * AssetConstants.EACH_IO_LINES;
			//实际每次读取的行数
			int eachLines = 0;
			//每次发生读取时的开始位置
			int beginPos = 0;
			//每次读取的字节数
			int eachTimeBytes = 0;
			List products = null;

			for(int i = 0; i < readCnt; i++) {
				content = new byte[contentSize];

				beginPos = readCnt * i;

				if(pos + AssetConstants.EACH_IO_LINES <= line) {
					//读取EACH_IO_LINES行
					eachLines = AssetConstants.EACH_IO_LINES;
					//每次读取的字节数
					eachTimeBytes = eachLines * AssetConstants.LINE_CHARS;
					mappedBuf.get(content,0,eachTimeBytes);
					products = ProductWrap.getProducts(content,
							beginPos,
							eachLines,
							params[0]);
					content = null;
				} else {
					//读取line - pos行
					eachLines = line - pos;
					eachTimeBytes = eachLines * AssetConstants.LINE_CHARS;
					mappedBuf.get(content,0,eachTimeBytes);
					products = ProductWrap.getProducts(content,
							beginPos,
							eachLines,
							params[0]);
					content = null;
				}
				pos = pos + eachLines;

				retList.addAll(products);
				/*if(params[0].equals(product.getCheckinStatus())) {
					retList.add(product);
				}*/
				//pos++;
				int progress = (pos* 100/line) ;


				if(oldProgress != progress) {
					oldProgress = progress;
					this.publishProgress(progress);
				}
			}
		} catch (FileNotFoundException e) {
			Log.e(TAG,e.getMessage());
		} catch (IOException e) {
			Log.e(TAG,e.getMessage());
		} finally {
			try {
				if(fc != null) {
					fc.close();
					fc = null;
				}
				if(fis != null) {
					fis.close();
					fis = null;
				}
			} catch (IOException e) {
				Log.e(TAG,e.getMessage());
			}
		}


		return retList;
	}


	/**
	 * randomAccess读写，每次读取一个字段
	 * @param params
	 * @return
	 */
	private List searchByRandom(String... params) {
		List retList = new ArrayList();
    	//FileInputStream fis = null;
    	//BufferedReader br = null;
    	//BufferedInputStream bis = null;
		RandomAccessFile random = null;
    	int pos = 0;
    	int oldProgress = 0;
		try {
			random = new RandomAccessFile(Environment.getExternalStorageDirectory().getPath()+File.separator+
					AssetConstants.PANDIAN_FILE_NAME,"rw");
			//br = new BufferedReader(new InputStreamReader(fis,Charset.forName("GBK")));
			//bis = new BufferedInputStream(fis);
			String content = null;
			Long size = random.length();
			int line = (int) (size / AssetConstants.LINE_CHARS);
			//while( (content = br.readLine()) != null) {
			for(int i = 0; i < line; i++) {
				random.seek(AssetConstants.LINE_CHARS*i);
				//Product product = ProductWrap.getProduct(content, pos);
				Product product = ProductWrap.getProduct(random, null, pos);
				Log.d(TAG,"pandian: "+product.getCheckinStatus());
				if(params[0].equals(product.getCheckinStatus())) {
					retList.add(product);
				}
				pos++;
				//Log.i(TAG,content);
				int progress = (pos* 100/line) ;
				
				
				if(oldProgress != progress) {
					oldProgress = progress;
					Log.e(TAG, "pos:"+ pos +" size: "+size + " line:" + line +" progress: "+progress);
					this.publishProgress(progress);
				}
			}

		} catch (FileNotFoundException e) {
			Log.e(TAG,e.getMessage());
		} catch (IOException e) {
			Log.e(TAG,e.getMessage());
		} finally {
			try {
				if(random != null) {
					random.close();
					random = null;
				}
			} catch (IOException e) {
				Log.e(TAG,e.getMessage());
			}
		}
    	
    	
    	return retList;
	}
}
